﻿using System;
using System.Windows.Forms;
using System.IO.Ports;
using Toolbox.util;

namespace Toolbox
{
    public partial class SerialPortForm : Form
    {

        String serialPortName;

        public SerialPortForm()
        {
            InitializeComponent();
        }

        private void SerialPortForm_Load(object sender, EventArgs e)
        {
            string[] ports = SerialPort.GetPortNames();//获取电脑上可用串口号
            comboBox1.Items.AddRange(ports);//给comboBox1添加数据
            comboBox1.SelectedIndex = comboBox1.Items.Count > 0 ? 0 : -1;//如果里面有数据,显示第0个

            comboBox2.Text = "9600";
            comboBox3.Text = "无";
            comboBox4.Text = "8";
            comboBox5.Text = "1";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // 打开/关闭串口按钮
            if(button1.Text == "打开")
            {
                // 设置串口号
                serialPort1.PortName = comboBox1.Text;
                serialPortName = comboBox1.Text;

                // 设置波特率
                serialPort1.BaudRate = int.Parse(comboBox2.Text);

                // 设置奇偶校验
                if (comboBox3.Text == "无")
                {
                    serialPort1.Parity = Parity.None;
                }
                else if (comboBox3.Text == "奇校验")
                {
                    serialPort1.Parity = Parity.Odd;
                }
                else if (comboBox3.Text == "偶校验")
                {
                    serialPort1.Parity = Parity.Even;
                }

                // 设置数据位
                serialPort1.DataBits = int.Parse(comboBox4.Text);

                // 设置停止位
                if (comboBox5.Text == "1")
                {
                    serialPort1.StopBits = StopBits.One;
                }
                else if (comboBox5.Text == "1.5")
                {
                    serialPort1.StopBits = StopBits.OnePointFive;
                }
                else if (comboBox5.Text == "2")
                {
                    serialPort1.StopBits = StopBits.Two;
                }

                try
                {
                    // 打开串口
                    serialPort1.Open();

                    // 按钮显示关闭
                    button1.Text = "关闭";
                }
                catch(Exception exception)
                {
                    MessageBox.Show("打开失败" + exception.ToString(), "提示！");
                }
                
                
            }
            else
            {
                // 关闭串口
                try
                {
                    serialPort1.Close();
                }
                catch(Exception exception)
                {
                    MessageBox.Show("关闭失败" + exception.ToString(), "提示！");
                }
                button1.Text = "打开";
            }
        }

        protected override void WndProc(ref Message m)
        {
            if(m.Msg == 0x0219)
            {
                // 设备改变
                if(m.WParam.ToInt32() == 0x8004)
                {
                    // USB串口拔出

                    // 重新获取串口
                    string[] ports = SerialPort.GetPortNames();
                    
                    // 清除串口下拉框数据
                    comboBox1.Items.Clear();
                    comboBox1.Items.AddRange(ports);
                    
                    if(button1.Text == "关闭")
                    {
                        // 用户打开过串口
                        if (!serialPort1.IsOpen)
                        {
                            // 用户打开的串口被关闭，说明热插拔是用户打开的串口
                            button1.Text = "打开";

                            // 释放掉原先的串口资源
                            serialPort1.Dispose();

                            comboBox1.SelectedIndex = comboBox1.Items.Count > 0 ? 0 : -1;//如果里面有数据,显示第0个
                        }
                        else
                        {
                            // 显示用户打开的那个串口号
                            comboBox1.Text = serialPortName;
                        }
                    }
                    else
                    {
                        // 用户没有打开过串口
                        comboBox1.SelectedIndex = comboBox1.Items.Count > 0 ? 0 : -1;//如果里面有数据,显示第0个
                    }
                }
                else if(m.WParam.ToInt32() == 0x8000)
                {
                    // USB串口连接上
                    // 重新获取串口
                    string[] ports = SerialPort.GetPortNames();

                    // 清除串口下拉框数据
                    comboBox1.Items.Clear();
                    comboBox1.Items.AddRange(ports);

                    if(button1.Text == "关闭")
                    {
                        // 用户打开过一个串口
                        comboBox1.Text = serialPortName;
                    }
                    else
                    {
                        comboBox1.SelectedIndex = comboBox1.Items.Count > 0 ? 0 : -1;//如果里面有数据,显示第0个
                    }
                }
            }
            base.WndProc(ref m);
        }

        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            // 获取可以读取的字节数
            int len = serialPort1.BytesToRead;

            // 创建缓存数据数组
            byte[] buff = new byte[len];

            // 把数据读取到buff数组
            serialPort1.Read(buff, 0, len);

            string str = HexUtils.bytesToHexStr(buff);

            // C#3.0以后代替委托的新方法
            // 对话框追加显示数据
            //Invoke(new Action(() => textBox1.AppendText(str + System.Environment.NewLine)));
            Invoke(new Action(() => {
                textBox1.Clear();
                Invoke(new Action(() => textBox1.AppendText(str + System.Environment.NewLine)));
            }));
        }

        private void button2_Click(object sender, EventArgs e)
        {
            // 发送按钮

            // 获取发送文本框里的数据
            string str = textBox2.Text.ToString();

            try
            {
                if(str.Length > 0)
                {
                    byte[] bytes = HexUtils.hexStrToBytes(str);
                    serialPort1.Write(bytes, 0, bytes.Length);
                }
            }
            catch (Exception)
            {

            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            // 清除发送按钮
            textBox2.Clear();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            // 清除接收按钮
            textBox1.Clear();
        }

    }
}
